package net.kleinhenz.droidshop.connector;

import java.net.MalformedURLException;
import java.net.URL;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;

public class Currencies
{
	public static URL USD = null;
	public static URL GBP = null;

	private static final Map<URL, CacheEntry> cache = new HashMap<URL, CacheEntry>();
	private static final long cacheTTL = 86400000; // one day
	
	static 
	{
		try
		{
			GBP = new URL("http://www.ecb.de/rss/fxref-gbp.html");
			USD = new URL("http://www.ecb.de/rss/fxref-usd.html");
		}
		catch (MalformedURLException e)
		{
			throw new RuntimeException(e);
		}
	}

	private class CacheEntry
	{
		public long time = -1;
		public double value = -1;
		
		public CacheEntry(long time, double value)
		{
			this.time = time;
			this.value = value;
		}
	}
	
	private class CurrencyRSSParser extends DefaultHandler 
	{
	    private StringBuffer contentBuffer = new StringBuffer();
	    private boolean inValue = false;
	    private double value = -1;
	    
	    public double retrieveCurrencyRate(URL url)
	    {
	        try 
	        {
	            SAXParserFactory factory = SAXParserFactory.newInstance();
	            SAXParser saxParser = factory.newSAXParser();
	            XMLReader reader = saxParser.getXMLReader();
	            reader.setContentHandler(this);
	            reader.parse(new InputSource(url.openStream()));
	            	            
	            return value;
	        }
	        catch (Exception e) 
	        {
	        	throw new RuntimeException(e);
	        }
	    }

	    @Override
	    public void startElement(String uri, String localName, String name,
	    	Attributes attributes) throws SAXException
	    {
	    	if (name.trim().endsWith(":value"))
	    		inValue = true;
	    }
	    
	    @Override
	    public void endElement(String uri, String localName, String name)
	    	throws SAXException
	    {
	    	if (name.trim().endsWith(":value") && value==-1)
	    	{
	    		inValue = false;
	    		value = Double.parseDouble(contentBuffer.toString());
	    	}	    		
	    }

		@Override
		public void characters(char[] ch, int start, int length)
				throws SAXException
		{
			if (inValue)
				contentBuffer.append(ch, start, length);
		}		
	}
	
	public double euroInCurrency(URL currency)
	{
		if (!cache.containsKey(currency) || cache.get(currency).time<(new Date().getTime()-cacheTTL))
		{
			CurrencyRSSParser parser = new CurrencyRSSParser();
			cache.put(currency, new CacheEntry(new Date().getTime(), parser.retrieveCurrencyRate(currency)));			
		}

		return cache.get(currency).value;
	}
}
